using System;
using System.Collections.Generic;

namespace Voodoo.Utils
{
	public class Explorer<T>
	{
		private bool _disposed;

		public List<int> Selection { get; protected set; } = new List<int>();

		public List<T> Items { get; protected set; } = new List<T>();

		public T this[int key]
		{
			get
			{
				return Items[key];
			}
			set
			{
				if (value != null)
				{
					Items[key] = value;
				}
			}
		}

		public event Action collectionChanged;

		public event Action<T> itemAdded;

		public event Action<int> itemRemoved;

		public event Action<int[]> contextClicked;

		public event Action<int[]> selectionChanged;

		public void Select(int[] indexes)
		{
			Selection.Clear();
			if (indexes != null && indexes.Length != 0)
			{
				Selection.AddRange(indexes);
			}
			this.selectionChanged?.Invoke(indexes ?? new int[0]);
		}

		public void ContextClick(int[] selection)
		{
			this.contextClicked?.Invoke(selection);
		}

		public void Fill(List<T> items)
		{
			Items.Clear();
			if (items != null && items.Count > 0)
			{
				Items.AddRange(items);
				this.collectionChanged?.Invoke();
			}
		}

		public void Insert(int index, T item)
		{
			if (item != null)
			{
				if (index >= 0 && index < Items.Count)
				{
					Items.Insert(index, item);
				}
				else
				{
					Items.Add(item);
				}
				this.itemAdded?.Invoke(item);
			}
		}

		public void RemoveAt(int index)
		{
			Items.RemoveAt(index);
			this.itemRemoved?.Invoke(index);
			Selection.Remove(index);
		}

		public void Clear()
		{
			Items.Clear();
		}

		public void Dispose()
		{
			if (!_disposed)
			{
				_disposed = true;
				Selection = null;
				Items = null;
				this.collectionChanged = null;
				this.itemAdded = null;
				this.itemRemoved = null;
				this.contextClicked = null;
				this.selectionChanged = null;
				GC.SuppressFinalize(this);
			}
		}
	}
}
